<template>
  <IccMonitorSolo
    ref="root"
    :player-type="playerType"
    :player-id="playerId"
    :use-nginx-proxy="useNginxProxy"
    :proxy-server-ip="proxyServerIp"
    :stream-server-ip="streamServerIp"
    :player-obj="playerObj"
    :record-date="recordDate"
    :show-top-control-bar="showTopControlBar"
    :player-icon-size="playerIconSize"
    :player-style="playerStyle"
    @initPlayerAfter="IccGroupConstant.playerInit=true"
    @clickPlayer="$emit('clickPlayer')"
  >
    <slot></slot>
  </IccMonitorSolo>
</template>

<script>
import {defineComponent} from 'vue';
import {v4 as uuidv4} from 'uuid';
import dayjs from 'dayjs';
import IccMonitorSolo from '../icc-monitor-solo/IccMonitorSolo.vue';
import IccGroupConstant from './IccGroupConstant.js';

export default defineComponent({
  name: 'IccMonitorGroup',
  components: {IccMonitorSolo},
  emits: ['clickPlayer', 'carousel'],
  props: {
    playerGroupKey: {
      type: String,
      required: true,
    },
    playerTotal: {
      type: Number,
      validator(value) {
        return value > 0;
      }
    },
    numInGroup: {
      type: Number,
      required: true,
      validator(value) {
        return value > 0;
      }
    },
    playCarousel: {
      type: Boolean,
      default: false,
    },
    playerType: {
      type: String,
      default: 'real',
      validator(value) {
        return ['real', 'record'].includes(value);
      }
    },
    playerId: {
      type: String,
      default: uuidv4(),
    },
    useNginxProxy: {
      type: Boolean,
      default: false,
    },
    proxyServerIp: String,
    streamServerIp: String,
    playerObj: {
      type: Object,
      default: () => ({
        id: '1000016$1$0$1',
        isOnline: false
      }),
    },
    recordDate: {
      type: String,
      validator(value) {
        return dayjs(value, 'YYYY-MM-DD', true).isValid();
      }
    },
    showTopControlBar: {
      type: Boolean,
      default: false,
    },
    playerIconSize: {
      type: Number,
      default: 25,
    },
    playerStyle: {
      type: Object,
      default: () => ({
        width: '100%',
        height: '100%',
      }),
    },
  },
  data() {
    return {
      IccGroupConstant: IccGroupConstant,
    };
  },
  mounted() {
    this.initPlayer();
  },
  unmounted() {
    const playerGroupKey = this.playerGroupKey;
    if (IccGroupConstant.playerGroup[playerGroupKey].carouselInterval) {
      this.endCarouselInterval();
    }

    IccGroupConstant.playerGroup[playerGroupKey] = {};
  },
  methods: {
    initPlayer() {
      const playerManager = this.$refs.root.playerManager;
      this.$refs.root.playerAdapter('stretching', playerManager);

      // 初始化全局变量IccGroupConstant.playerGroup
      const playerGroupKey = this.playerGroupKey;
      if (!IccGroupConstant.playerGroup[playerGroupKey].noFirstInit) {
        IccGroupConstant.playerGroup[playerGroupKey] = {
          noFirstInit: true, // 此次后非首次
          playerTotal: this.playerTotal,
          groupTotal: Math.ceil(this.playerTotal / this.numInGroup),
          numInGroup: this.numInGroup,
          firstNumInGroup: this.playerTotal <= this.numInGroup ? this.playerTotal : this.numInGroup,
          lastNumInGroup: this.playerTotal % this.numInGroup === 0 ? this.numInGroup : this.playerTotal % this.numInGroup,
          firstLoadedFirstGroup: true,
          carouselInterval: null,
          currentCarouselIndex: 0,
          group: [],
        };
      }

      // 更新全局变量IccGroupConstant.playerGroup
      const player = {
        thisVue: this.$refs.root,
        playerIns: playerManager,
        playerObj: this.playerObj,
        recordDate: this.verifyRecordDate(this.recordDate) ? this.recordDate : dayjs().format('YYYY-MM-DD'),
      };
      const groupLastIndex = IccGroupConstant.playerGroup[playerGroupKey].group.length - 1;
      if (
        groupLastIndex === -1 ||
        IccGroupConstant.playerGroup[playerGroupKey].group[groupLastIndex].player.length
        === IccGroupConstant.playerGroup[playerGroupKey].numInGroup
      ) {
        IccGroupConstant.playerGroup[playerGroupKey].group.push({
          init: false,
          loaded: false,
          player: [player],
        });
      } else {
        IccGroupConstant.playerGroup[playerGroupKey].group[groupLastIndex].player.push(player);
      }

      const nowGroupLastIndex = IccGroupConstant.playerGroup[playerGroupKey].group.length - 1;
      if (nowGroupLastIndex === 0) {
        // 第1组
        if (
          IccGroupConstant.playerGroup[playerGroupKey].group[nowGroupLastIndex].player.length
          === IccGroupConstant.playerGroup[playerGroupKey].firstNumInGroup
        ) {
          IccGroupConstant.playerGroup[playerGroupKey].group[nowGroupLastIndex].init = true;
        }
      } else if (
        nowGroupLastIndex === IccGroupConstant.playerGroup[playerGroupKey].groupTotal - 1
      ) {
        // 最后一组
        if (
          IccGroupConstant.playerGroup[playerGroupKey].group[nowGroupLastIndex].player.length
          === IccGroupConstant.playerGroup[playerGroupKey].lastNumInGroup
        ) {
          IccGroupConstant.playerGroup[playerGroupKey].group[nowGroupLastIndex].init = true;
        }
      } else if (
        IccGroupConstant.playerGroup[playerGroupKey].group[nowGroupLastIndex].player.length
        === IccGroupConstant.playerGroup[playerGroupKey].numInGroup
      ) {
        IccGroupConstant.playerGroup[playerGroupKey].group[nowGroupLastIndex].init = true;
      }

      // 首次加载第一组 && 第一组初始化完成
      if (
        IccGroupConstant.playerGroup[playerGroupKey].firstLoadedFirstGroup &&
        IccGroupConstant.playerGroup[playerGroupKey].group[0].player.length ===
        IccGroupConstant.playerGroup[playerGroupKey].firstNumInGroup
      ) {
        // 若此时播放器未初始化完成则设置定时器，待播放器初始化完成后再继续
        if (!IccGroupConstant.playerInit) {
          let playerInitInterval = setInterval(() => {
            if (!IccGroupConstant.playerInit) {
              return;
            }

            // 播放第一组
            IccGroupConstant.playerGroup[playerGroupKey].group[0].loaded = true;
            IccGroupConstant.playerGroup[playerGroupKey].group[0].player.forEach((item) => {
                item.thisVue.playerNoLoadIcon = false;
                item.thisVue.realPlay(item.playerIns, item.playerObj);
              }
            );

            // 开始轮播
            this.startCarouselInterval();

            // 关闭当前定时器
            clearInterval(playerInitInterval);
            playerInitInterval = null;
          }, 1000);
        } else {
          // 播放第一组
          IccGroupConstant.playerGroup[playerGroupKey].group[0].loaded = true;
          IccGroupConstant.playerGroup[playerGroupKey].group[0].player.forEach((item) => {
            item.thisVue.playerNoLoadIcon = false;
            item.thisVue.realPlay(item.playerIns, item.playerObj);
          });

          // 开始轮播
          this.startCarouselInterval();
        }

        IccGroupConstant.playerGroup[playerGroupKey].firstLoadedFirstGroup = false;
      }
    },
    verifyRecordDate(date) {
      if (!date) return false;

      // 录像回放日期格式不正确
      const parsedDate = dayjs(date, {strict: true});
      if (!parsedDate.isValid() || parsedDate.format('YYYY-MM-DD') !== date) {
        return false;
      }

      return true;
    },
    startCarouselInterval() {
      const playerGroupKey = this.playerGroupKey;

      // 不需要轮播
      if (!this.playCarousel || IccGroupConstant.playerGroup[playerGroupKey].groupTotal <= 1) return;

      // 已存在轮播
      if (IccGroupConstant.playerGroup[playerGroupKey].carouselInterval) return;

      IccGroupConstant.playerGroup[playerGroupKey].carouselInterval = setInterval(() => {
        this.realPlayGroup();

        // 轮播事件
        this.$emit('carousel');
      }, 10000);
    },
    realPlayGroup(curCarouselIndex, beforeCarouselIndex) {
      const playerGroupKey = this.playerGroupKey;

      // 当前轮播组的索引
      let currentCarouselIndex = curCarouselIndex !== undefined ? curCarouselIndex
        : IccGroupConstant.playerGroup[playerGroupKey].currentCarouselIndex + 1;
      if (currentCarouselIndex === IccGroupConstant.playerGroup[playerGroupKey].groupTotal) {
        currentCarouselIndex = 0;
      }

      // 当前轮播组的索引比实际轮播组数大，则跳过此次轮播等待下一次
      if (currentCarouselIndex >= IccGroupConstant.playerGroup[playerGroupKey].group.length) {
        return;
      }

      // 当前轮播组未初始化完成 || 当前轮播组正在播放，则跳过此次轮播等待下一次
      if (
        !IccGroupConstant.playerGroup[playerGroupKey].group[currentCarouselIndex].init ||
        IccGroupConstant.playerGroup[playerGroupKey].group[currentCarouselIndex].loaded
      ) {
        return;
      }

      // 播放当前组
      IccGroupConstant.playerGroup[playerGroupKey].group[currentCarouselIndex].loaded = true;
      IccGroupConstant.playerGroup[playerGroupKey].group[currentCarouselIndex].player.forEach((item) => {
        item.thisVue.playerNoLoadIcon = false;
        item.thisVue.realPlay(item.playerIns, item.playerObj);
      });

      // 关闭前一组
      const formerCarouselIndex = beforeCarouselIndex ? beforeCarouselIndex
        : IccGroupConstant.playerGroup[playerGroupKey].currentCarouselIndex;
      IccGroupConstant.playerGroup[playerGroupKey].group[formerCarouselIndex].loaded = false;
      IccGroupConstant.playerGroup[playerGroupKey].group[formerCarouselIndex].player.forEach((item) => {
        item.thisVue.playerNoLoadIcon = true;
        item.thisVue.closePlayer(item.playerIns);
      });

      // 索引移动
      IccGroupConstant.playerGroup[playerGroupKey].currentCarouselIndex = currentCarouselIndex;
    },
    endCarouselInterval() {
      const playerGroupKey = this.playerGroupKey;
      clearInterval(IccGroupConstant.playerGroup[playerGroupKey].carouselInterval);
      IccGroupConstant.playerGroup[playerGroupKey].carouselInterval = null;
    },
  }
});
</script>